﻿using System;

namespace SoftwareConsulting.BI11.NumericalMethods.MatrixAlgebra
{
    /// <summary>
    /// Класс вычисления детерминанты матрицы
    /// </summary>
    public static class MatrixDeterminantFinder
    {
        /// <summary>
        /// Возвращает детерминанту квадратной матрицы
        /// </summary>
        /// <param name="squareMatrixComponents">элементы квадратной матрицы</param>
        /// <param name="matrixDimensionality">размерность матрицы</param>
        /// <returns></returns>
        public static double GetDeterminant(double[,] squareMatrixComponents, int matrixDimensionality)
        {
            double result = 0;
            int[] pivots = new int[0];
            squareMatrixComponents = (double[,])squareMatrixComponents.Clone();
            MatrixLowerUpperDecompositionFinder matrix = new MatrixLowerUpperDecompositionFinder(squareMatrixComponents, matrixDimensionality, matrixDimensionality);            
            result = rMatrixLuDet(matrix.GetSolutionCompactLUMatrix(), matrix.GetSolutionPivots(), matrixDimensionality);
            return result;
        }
        
        /// <summary>
        /// Возвращает детерминанту квадратной матрицы
        /// </summary>
        /// <param name="lowerUpperMatrixDecomposition">LU-декомпозиция матрицы</param>
        /// <param name="pivots">таблица вращений матрицы</param>
        /// <param name="matrixDimensionality">размерность матрицы</param>
        /// <returns></returns>
        public static double rMatrixLuDet(double[,] lowerUpperMatrixDecomposition, int[] pivots, int matrixDimensionality)
        {
            double result = 1;            
            int sign = 1;            
            for (int i = 0; i <= matrixDimensionality - 1; i++)
            {
                result = result * lowerUpperMatrixDecomposition[i, i];
                if (pivots[i] != i)
                    sign = -sign;                
            }
            result = result * sign;
            return result;
        }
    }
}
